using System.Linq;
using ExampleMvcApplication.Controllers;
using ExampleMvcApplication.Models.Response;
using SmallMvc;

namespace ExampleMvcApplication.Views
{
    public abstract class Master<TModel> : SmallView<TModel> where TModel : MasterModel
    {
        public static readonly string ValidationMessageCssClassName = "field-validation-error";
        public static readonly string ValidationSummaryCssClassName = "validation-summary-errors";
        protected abstract string RenderMainContent(TModel model);
        protected abstract string RenderTitleContent();

        protected override string Render(TModel model)
        {
            return
                html._(
                    head._(
                        title._(RenderTitleContent()),
                        link.href("../../Content/Site.css").rel("stylesheet").type("text/css")
                        ),
                    body._(
                        div._class("page")._(
                            div.id("header")._(
                                div.id("title")._(
                                    h1._("My MVC Application")
                                    ),
                                div.id("logindisplay")._(
                                    RenderLogOnUserControl(model.IsAuthenticated, model.UserNameOrNull)
                                    ),
                                div.id("menucontainer")._(
                                    ul.id("menu")._(
                                        li._(a.href(UrlResolver.UrlFor<HomeController>(x => x.Index()))._("Home")),
                                        li._(a.href(UrlResolver.UrlFor<HomeController>(x => x.About()))._("About"))
                                        )
                                    )
                                ),
                            div.id("main")._(
                                RenderMainContent(model),
                                div.id("footer")._(
                                    )
                                )
                            )
                        )
                    );
        }

        private string RenderLogOnUserControl(bool isAuthenticated, string nameOrNull)
        {
            var returnUrl = ViewContext.RequestContext.HttpContext.Request.Url.PathAndQuery;
            if (isAuthenticated)
            {
                return "Welcome " + b._(nameOrNull) + a.href(UrlResolver.UrlFor<AccountController>(x => x.LogOff()))._("Log Off") +
                       " | " + a.href(UrlResolver.UrlFor<AccountController>(x => x.ChangePassword()))._("Change Password");
            }
            return a.href(UrlResolver.UrlFor<AccountController>(x => x.LogOn(returnUrl)))._("Log On");
        }


        protected string RenderError(string modelName)
        {
            var message = GetErrorMessage(modelName);
            if (message == null) return string.Empty;
            return span._class(ValidationMessageCssClassName)._(message);
        }

        private string GetErrorMessage(string modelName)
        {
            var viewData = ViewContext.ViewData;
            if (!viewData.ModelState.ContainsKey(modelName))
            {
                return null;
            }

            var modelState = viewData.ModelState[modelName];
            var modelErrors = (modelState == null) ? null : modelState.Errors;
            var modelError = ((modelErrors == null) || (modelErrors.Count == 0)) ? null : modelErrors[0];

            if (modelError == null)
            {
                return null;
            }

            return modelError.ErrorMessage;
        }

        protected string RenderErrorSummary()
        {
            return
                ul._class(ValidationSummaryCssClassName)._(
                    me => li._(me.ErrorMessage),
                    ViewContext.ViewData.ModelState.Values.SelectMany(x => x.Errors)
                    ).IfChildren();
        }
    }
}